package
{
	public class TileMap
	{
		public var xw:Number;
		// 格半宽
		public var yw:Number;
		// 格半高
		public var tw:Number;
		// 格宽
		public var th:Number;
		// 格高
		public var rows:Number;
		// 列高
		public var cols:Number;
		// 行宽
		private var fullrows:Number;
		private var fullcols:Number;
		public var minX:Number;
		public var minY:Number;
		public var maxX:Number;
		private var maxY:Number;
		private var grid:Array;
		private var rend:VectorRenderer;
		private var BUILD_STEPS_REMAINING:Number;
		private const CHAR_PAD:uint = 48;

		public function TileMap(rows:Number, cols:Number, xw:Number, yw:Number)
		{
			this.xw = xw;
			this.yw = yw;
			this.tw = 2 * this.xw;
			this.th = 2 * this.yw;
			this.rows = rows;
			this.cols = cols;
			this.fullrows = this.rows + 2;
			this.fullcols = this.cols + 2;
			this.minX = this.tw;
			this.minY = this.th;
			this.maxX = this.tw + rows * this.tw;
			this.maxY = this.th + cols * this.th;
			this.grid = new Array();
			this.BUILD_STEPS_REMAINING = 9;
			this.rend = new VectorRenderer();
			this.rend.Clear();
		}

		//
		public function Building():Boolean
		{
			var row:int;
			var column:int;
			// 构建Tiles
			if (this.BUILD_STEPS_REMAINING == 9)
			{
				this.grid = new Array(this.fullrows);
				for (column = 0; column < this.fullrows; column++)
				{
					this.grid[column] = new Array(this.fullcols);
					for (row = 0; row < this.fullcols; row++)
					{
						this.grid[column][row] = new TileMapCell(column, row, column * this.tw + this.xw, row * this.th + this.yw, this.xw, this.yw);
					}
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记右邻居
			else if (this.BUILD_STEPS_REMAINING == 8)
			{
				for (column = 0; column < this.fullrows - 1; column++)
				{
					for (row = 0; row < this.fullcols; row++)
					{
						this.grid[column][row].LinkR(this.grid[column + 1][row]);
					}
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记左邻居
			else if (this.BUILD_STEPS_REMAINING == 7)
			{
				for (column = 1; column < this.fullrows; column++)
				{
					for (row = 0; row < this.fullcols; row++)
					{
						this.grid[column][row].LinkL(this.grid[column - 1][row]);
					}
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记下邻居
			else if (this.BUILD_STEPS_REMAINING == 6)
			{
				for (column = 0; column < this.fullrows; column++)
				{
					for (row = 0; row < this.fullcols - 1; row++)
					{
						this.grid[column][row].LinkD(this.grid[column][row + 1]);
					}
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记上邻居
			else if (this.BUILD_STEPS_REMAINING == 5)
			{
				for (column = 0; column < this.fullrows; column++)
				{
					for (row = 1; row < this.fullcols; row++)
					{
						this.grid[column][row].LinkU(this.grid[column][row - 1]);
					}
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记最后面Tile状态
			else if (this.BUILD_STEPS_REMAINING == 4)
			{
				for (column = 0; column < this.fullrows; column++)
				{
					this.grid[column][0].SetState(TileMapCell.TID_FULL);
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记最后面Tile状态
			else if (this.BUILD_STEPS_REMAINING == 3)
			{
				for (column = 0; column < this.fullrows; column++)
				{
					this.grid[column][this.fullcols - 1].SetState(TileMapCell.TID_FULL);
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记最后面Tile状态
			else if (this.BUILD_STEPS_REMAINING == 2)
			{
				for (row = 0; row < this.fullcols; row++)
				{
					this.grid[0][row].SetState(TileMapCell.TID_FULL);
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			// 标记最后面Tile状态
			else if (this.BUILD_STEPS_REMAINING == 1)
			{
				for (row = 0; row < this.fullcols; row++)
				{
					this.grid[this.fullrows - 1][row].SetState(TileMapCell.TID_FULL);
				}
				this.BUILD_STEPS_REMAINING--;
				return true;
			}
			return false;
		}

		//
		public function ClearGrid():void
		{
			for (var column:int = 0; column < this.grid.length; column++)
			{
				for (var row:int = 0; row < this.grid[column].length; row++)
				{
					this.grid[column][row].next = null;
					this.grid[column][row].prev = null;
				}
			}
		}

		//
		public function GetTile_S(x:Number, y:Number):TileMapCell
		{
			return this.grid[Math.floor(x / this.tw)][Math.floor(y / this.th)];
		}

		//
		public function GetTile_V(p:Vector2):TileMapCell
		{
			return this.grid[Math.floor(p.x / this.tw)][Math.floor(p.y / this.th)];
		}

		//
		public function GetTile_I(column:int, row:int):TileMapCell
		{
			return this.grid[column][row];
		}

		//
		public function GetIndex_S(v:Vector2, x:Number, y:Number):void
		{
			v.x = Math.floor(x / this.tw);
			v.y = Math.floor(y / this.th);
		}

		//
		public function GetIndex_V(v:Vector2, p:Vector2):void
		{
			v.x = Math.floor(p.x / this.tw);
			v.y = Math.floor(p.y / this.th);
		}

		//
		public function GetTileStates():String
		{
			var output:String = "";
			for (var column:int = 0; column < this.rows; column++)
			{
				for (var row:int = 0; row < this.cols; row++)
				{
					output += this.grid[column + 1][row + 1].ID;
				}
			}
			return output;
		}

		//
		public function SetTileState(column:int, row:int, char:int):void
		{
			this.grid[column + 1][row + 1].SetState(char - this.CHAR_PAD);
		}

		//
		private function SetTileStates(instr:String):void
		{
			var row:int;
			var column:int;
			var charList:Array = new Array(this.rows);
			for (column = 0; column < this.rows; column++)
			{
				charList[column] = new Array(this.cols);
				for (row = 0; row < this.cols; row++)
				{
					charList[column][row] = instr.charCodeAt(column * this.cols + row);
				}
			}
			//
			for (column = 0; column < this.rows; column++)
			{
				for (row = 0; row < this.cols; row++)
				{
					this.grid[column + 1][row + 1].SetState(charList[column][row] - this.CHAR_PAD);
				}
			}
		}
	}
}